﻿using Shake.Business.Infrastructures;
using Shake.Domain.Filters;
using Shake.Framework.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using Shake.Framework.Models;
using Shake.Domain.Models;
using Shake.Domain.Dto;

namespace Shake.Business.Services
{
    public class DepartmentService : IDepartmentService
    {
        public IRepository Repository { get; set; }

        public PaginationContent GetDepartments(DepartmentFilter filter, PageArgument page)
        {
            using (var factory = Repository.CreateSessionFactory())
            {
                var session = factory.GetCurrentSession();
                var query = session.QueryOver<Department>();
                if (!string.IsNullOrEmpty(filter.Name))
                {
                    query = query.Where(t => t.Name.Contains(filter.Name));
                }
                if (!string.IsNullOrEmpty(filter.ParentId))
                {
                    query = query.Where(t => t.ParentId == filter.ParentId);
                }

                var results = query.OrderBy(t => t.Sort).Desc.Skip((page.Page - 1) * page.Pages).List();
                var total = query.RowCount();

                return new PaginationContent
                {
                    Datas = results,
                    Filter = filter,

                    Total = total
                };
            }
        }

        public List<Department> GetAllDepartment(DepartmentFilter filter)
        {
            using (var factory = Repository.CreateSessionFactory())
            {
                var session = factory.GetCurrentSession();
                var query = session.QueryOver<Department>();
                if (!string.IsNullOrEmpty(filter.Name))
                {
                    query = query.Where(t => t.Name.Contains(filter.Name));
                }
                if (!string.IsNullOrEmpty(filter.ParentId))
                {
                    query = query.Where(t => t.ParentId == filter.ParentId);
                }

                var results = query.List();

                return results.ToList();
            }
        }

        public Department GetDepartments(string id)
        {
            using (var factory = Repository.CreateSessionFactory())
            {
                var session = factory.GetCurrentSession();
                var query = session.QueryOver<Department>();

                var departments = query.Where(t => t.Id == id).List();
                if (departments.Count == null) return null;
                return departments.FirstOrDefault();
            }
        }

        public void Create(List<Department> departments)
        {
            if (departments == null) throw new Exception("参数异常");
            foreach (var department in departments)
            {
                department.Id = Guid.NewGuid().ToString("N");
                if (!string.IsNullOrEmpty(department.ParentId))
                {
                    var record = this.GetDepartments(department.ParentId);
                    if (record != null) department.Path = record.Path == null ? department.Id : string.Format("{0}|{1}", record.Path, record.Id);
                }
            }
            Repository.InsertMany(departments);
        }

        public void Create(Department department)
        {
            if (department == null) throw new Exception("参数异常");
            department.Id = Guid.NewGuid().ToString("N");
            Repository.Insert(department);
        }

        public void Remove(List<Department> departments)
        {
            if (departments == null) return;
            Repository.DeleteMany(departments);
        }

        public void Update(List<Department> departments)
        {
            if (departments == null) throw new Exception("参数异常");
            foreach (var department in departments)
            {
                if (!string.IsNullOrEmpty(department.ParentId))
                {
                    var record = this.GetDepartments(department.ParentId);
                    if (record != null) department.Path = record.Path == null ? department.Id : string.Format("{0}|{1}", record.Path, record.Id);
                }
            }
            Repository.UpdateMany(departments);
        }

        public List<DepartmentDto> AsTree()
        {
            var departments = GetAllDepartment(new DepartmentFilter());
            var departmentDtos = departments.Select(t => new DepartmentDto
            {
                expanded = true,
                id = t.Id,
                pid = t.ParentId,
                text = t.Name,
                items = new List<DepartmentDto>()
            }).ToList();

            for (int i = 0; i < departmentDtos.Count; i++)
            {
                var departmentDto = departmentDtos[i];
                departmentDto.items = departmentDtos.Where(t => t.pid == departmentDto.id).ToList();
            }
            return departmentDtos.Where(t => t.pid == null).ToList();
        }
    }
}
